home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung CD 2 (Tewi)(1994).iso / doc / mir / replace1.c < prev    next >
Text File  |  1992-07-02  |  12KB  |  345 lines

  1. /*
  2.  *  usage:  replace1  input  output  [ replacement_table ]
  3.  *
  4.  * REPLACE1 Replaces each byte in an input file with exactly one
  5.  *          alternative ASCII character.  The default replacement table
  6.  *          built into the program is one that replaces high-bit-set
  7.  *          graphic characters with reasonable equivalents.  An alternate
  8.  *          table may be used simply by naming it as an argument.  This
  9.  *          high speed 1 for 1 replacement can be used for anything from
  10.  *          EBCDIC/ASCII conversion to a crude encryption.
  11.  *
  12.  *  input:  [1] Any file
  13.  *          [2] The optional replacement table consists of ASCII lines in
  14.  *          any order.  Each line has two columns separated by white space.
  15.  *          The first column in each line is the incoming character or a
  16.  *          range of characters separated by only a hyphen; the second
  17.  *          column is the replacement. Non-printable characters are shown
  18.  *          by a backslash followed by two hex digits (for example, \08 for
  19.  *          backspace).  Backslash itself is shown by \5C.  Any characters
  20.  *          not in the replacement table are retained.
  21.  *
  22.  *  output: File same size as input with some/all characters replaced.
  23.  *
  24.  *  writeup: MIR TUTORIAL TWO, topic 6
  25.  *
  26.  *  Written:    Douglas Lowry   Mar 06 92
  27.  *              Copyright (C) 1992 Marpex Inc.
  28.  *
  29.  *    The MIR (Mass Indexing and Retrieval) Tutorials explain detailed
  30.  *    usage and co-ordination of the MIR family of programs to analyze,
  31.  *    prepare and index databases (small through gigabyte size), and
  32.  *    how to build integrated retrieval software around the MIR search
  33.  *    engine.  The fifth of the five MIR tutorial series explains how
  34.  *    to extend indexing capability into leading edge search-related
  35.  *    technologies.  For more information, GO IBMPRO on CompuServe;
  36.  *    MIR files are in the DBMS library.  The same files are on the
  37.  *    Canada Remote Systems BBS.  A diskette copy of the Introduction
  38.  *    is available by mail ($10 US... check, Visa or Mastercard);
  39.  *    diskettes with Introduction, Tutorial ONE software and the
  40.  *    shareware Tutorial ONE text cost $29.  Shareware registration
  41.  *    for a tutorial is also $29.
  42.  *
  43.  *    E-mail...
  44.  *                Compuserve  71431,1337
  45.  *                Internet    doug.lowry%canrem.com
  46.  *                UUCP        canrem!doug.lowry
  47.  *                Others:     doug.lowry@canrem.uucp
  48.  *
  49.  *    FAX...                  416 963-5677
  50.  *
  51.  *    "Snail mail"...         Douglas Lowry, Ph.D.
  52.  *                            Marpex Inc.
  53.  *                            5334 Yonge Street, #1102
  54.  *                            North York, Ontario
  55.  *                            Canada  M2N 6M2
  56.  *
  57.  *    Related database consultation and preparation services are
  58.  *    available through:
  59.  *              Innotech Inc., 2001 Sheppard Avenue E., Suite #118,
  60.  *              North York, Ontario  Canada   M2J 4Z7
  61.  *              Tel.  416 492-3838   FAX  416 492-3843
  62.  *
  63.  *  This program is free software; you may redistribute it and/or
  64.  *  modify it under the terms of the GNU General Public License as
  65.  *  published by the Free Software Foundation; either version 2 of
  66.  *  the License, or (at your option) any later version.
  67.  *
  68.  *  This program is distributed in the hope that it will be useful,
  69.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  70.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  71.  *  GNU General Public License for more details.
  72.  *
  73.  *  You should have received a copy of the GNU General Public License
  74.  *  (file 05LICENS) along with this program; if not, write to the
  75.  *  Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
  76.  *  USA.
  77.  */
  78.  
  79. #include <stdio.h>
  80.  
  81. #define     repeat      for(;;)
  82. #define     MAX_BYTES   2048
  83.  
  84. /*
  85.  * declarations 
  86.  */
  87.  
  88. typedef     enum        _bool
  89.              { FALSE = 0, TRUE = 1 }  Bool;
  90.  
  91.     void        Usage_(), process(), load_table() ;
  92.     unsigned char   get_hex() ;
  93.     char        *Cmdname_() {    return( "replace1" );  }
  94.  
  95. /*
  96.  * MAIN
  97.  */
  98.  
  99. main( argc, argv )
  100.     int  argc;
  101.     char **argv;
  102. {
  103. /*  This table strips accents, turns box characters to asterisks, bar
  104.     characters to equals, pointers to o, and all else from hex 7f up
  105.     to blanks      */
  106.  
  107.     unsigned char   table[256] = {
  108.      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
  109.     16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  110.    ' ','!','"','#','$','%','&', 39,'(',')','*','+',',','-','.','/',
  111.    '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?',
  112.    '@','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
  113.    'P','Q','R','S','T','U','V','W','X','Y','Z','[', 92,']','^','_',
  114.    '`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
  115.    'p','q','r','s','t','u','v','w','x','y','z','{','|','}','~', 32,
  116. /*  Ç   ü   é   â   ä   à   å   ç   ê   ë   è   ï   î   ì   Ä   Å  */
  117.    'c','u','e','a','a','a','a','c','e','e','e','i','i','i','A','A',
  118. /*  É   æ   Æ   ô   ö   ò   û   ù   ÿ   Ö   Ü   ¢   £   ¥   ₧   ƒ  */
  119.    'E','a','A','o','o','o','u','u','y','o','u', 32, 32, 32, 32, 32,
  120. /*  á   í   ó   ú   ñ   Ñ   ª   º   ¿   ⌐   ¬   ½   ¼   ¡   «   »  */
  121.    'a','i','o','u','n','N','a','o', 32, 32, 32, 32, 32, 32,'o','o',
  122. /*  ░   ▒   ▓   │   ┤   ╡   ╢   ╖   ╕   ╣   ║   ╗   ╝   ╜   ╛   ┐  */
  123.    '=','=','=', 32, 32, 32, 32, 32, 32, 32,'*','*','*', 32, 32, 32,
  124. /*  └   ┴   ┬   ├   ─   ┼   ╞   ╟   ╚   ╔   ╩   ╦   ╠   ═   ╬   ╧  */
  125.     32, 32, 32, 32, 32, 32, 32, 32,'*','*', 32, 32, 32,'*', 32, 32,
  126. /*  ╨   ╤   ╥   ╙   ╘   ╒   ╓   ╫   ╪   ┘   ┌   █   ▄   ▌   ▐   ▀  */
  127.     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
  128. /*  α   ß   Γ   π   Σ   σ   µ   τ   Φ   Θ   Ω   δ   ∞   φ   ε   ∩  */
  129.     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
  130. /*  ≡   ±   ≥   ≤   ⌠   ⌡   ÷   ≈   °   ∙   ·   √   ⁿ   ²   ■      */
  131.     32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
  132.             };
  133.  
  134.     FILE    *fp, *fp_out ;
  135.     char    c10 ;
  136.     Bool    get_table ;     /*  user specifies table name   */
  137.  
  138.     /*  usage:  replace1  input  output  [ replacement_table ] */
  139.  
  140.     if( argc < 3 || argc > 4 )
  141.         Usage_() ;
  142.     c10 = argv[1][0] ;
  143.     if( c10 == '-' || c10 == '/' || c10 == '?' )
  144.         Usage_() ;
  145.  
  146.     if( argc == 4 )
  147.     {
  148.         if(( fp = fopen( argv[3], "r" )) == NULL )
  149.         {
  150.             fprintf( stderr, "\nUnable to open file %s.\n", argv[3] );
  151.             Usage_();
  152.         }
  153.         load_table( fp, table ) ;
  154.         fclose( fp ) ;
  155.  
  156.     }
  157.  
  158.     if(( fp = fopen( argv[1], "rb" )) == NULL )
  159.     {
  160.         fprintf( stderr, "\nUnable to open file %s.\n", argv[1] );
  161.             Usage_();
  162.     }
  163.  
  164.     if(( fp_out = fopen( argv[2], "wb" )) == NULL )
  165.     {
  166.         fprintf( stderr, "\nUnable to open file %s.\n", argv[2] );
  167.             Usage_();
  168.     }
  169.  
  170.     process( fp, fp_out, table ) ;
  171.  
  172.     fclose( fp );
  173.     fclose( fp_out );
  174.     exit( 0 );
  175. }
  176. /*
  177.  *  Usage
  178.  */
  179.     void
  180. Usage_()
  181. {
  182.     fprintf( stderr,
  183. "Usage:  %s  input  output  [ replacement_table ]\n\n\
  184.         Replaces each byte in an input file with exactly one\n\
  185.         alternative ASCII character.  The default replacement table\n\
  186.         built into the program is one that replaces high-bit-set\n",
  187.             Cmdname_() );
  188.     fprintf( stderr,
  189. "        graphic characters with reasonable equivalents.  An alternate\n\
  190.         table may be used simply by naming it as an argument.  This\n\
  191.         high speed 1 for 1 replacement can be used for anything from\n\
  192.         EBCDIC/ASCII conversion to a crude encryption.\n\
  193. input:  [1] Any file\n" ) ;
  194.     fprintf( stderr,
  195. "        [2] The optional replacement table consists of ASCII lines in\n\
  196.         any order.  Each line has two columns separated by white space.\n\
  197.         The first column in each line is the incoming character or a\n\
  198.         range of characters separated by only a hyphen; the second\n" ) ;
  199.     fprintf( stderr,
  200. "        column is the replacement. Non-printable characters are shown\n\
  201.         by a backslash followed by two hex digits (for example, \\08 for\n\
  202.         backspace).  Backslash itself is shown by \\5C.  Any characters\n\
  203.         not in the replacement table are retained.\n\
  204. output: File same size as input with some/all characters replaced.\n" ) ;
  205.     fprintf( stderr, "writeup: MIR TUTORIAL TWO, topic 6\n\n" ) ;
  206.  
  207.     exit( 1 ) ;
  208. }
  209. /*
  210.  *  PROCESS
  211.  */
  212.     void
  213. process( fp_in, fp_out, table )
  214.     FILE    *fp_in, *fp_out ;
  215.     unsigned char       table[256] ;
  216. {
  217.  
  218.     unsigned char   buf[ MAX_BYTES ],
  219.                     out;
  220.     int             len, i ;
  221.  
  222.     while(( len = fread( buf, sizeof( char ), MAX_BYTES, fp_in )) > 0 )
  223.     {
  224.         for( i = 0; i < len ; i++ )
  225.         {
  226.             out = table[ buf[ i ] ];
  227.             if( fputc( out, fp_out ) != out )
  228.             {
  229.                 fprintf( stderr, "FATAL... Unable to write.\n\n" ) ;
  230.                 exit( 1 ) ;
  231.             }
  232.         }
  233.     }
  234.  
  235.     return ;
  236. }
  237. /*
  238.  *  LOAD_TABLE
  239.  */
  240.     void
  241. load_table( fp, table )
  242.     FILE    *fp ;
  243.     unsigned char   table[256] ;
  244. {
  245.     unsigned char   buf[ 120 ],
  246.             replace,        /*  replacement value   */
  247.             from, to ;
  248.     Bool    foul_up ;
  249.     int     len, pt, i ;
  250.  
  251.     for( i = 0 ; i < 256 ; i++ )
  252.         table[i] = ( unsigned char ) i ;
  253.     foul_up = FALSE ;
  254.  
  255.     while( fgets( buf, 120, fp ) != NULL )
  256.     {
  257.         len = strlen( buf ) ;
  258.         if( len > 110 )
  259.             foul_up = TRUE ;
  260.         pt = 0 ;
  261.         while( isspace( buf[ pt ] ))
  262.             pt++ ;
  263.  
  264.         /*  Get first column    */
  265.  
  266.         if( buf[pt] == '\\' )
  267.         {
  268.             from = get_hex( &buf[pt+1], &foul_up );
  269.             pt += 3 ;
  270.         }
  271.         else
  272.             from = buf[ pt++ ] ;
  273.  
  274.         /*  Check if a range in first column    */
  275.  
  276.         if( buf[pt] == '-' )
  277.         {
  278.             pt++ ;
  279.             if( buf[pt] == '\\' )
  280.             {
  281.                 to = get_hex( &buf[pt+1], &foul_up );
  282.                 pt += 3 ;
  283.             }
  284.             else
  285.                 to = buf[ pt++ ] ;
  286.         }
  287.         else
  288.             to = from ;
  289.     
  290.         /*  Get the second column = replacement character   */
  291.  
  292.         while( isspace( buf[ pt ] ))
  293.             pt++ ;
  294.         if( buf[pt] == '\\' )
  295.         {
  296.             replace = get_hex( &buf[pt+1], &foul_up );
  297.             pt += 3 ;
  298.         }
  299.         else
  300.             replace = buf[ pt++ ] ;
  301.  
  302.         for( i = from ; i < to + 1 ; i++ )
  303.             table[ i ] = replace ;
  304.  
  305.         if( foul_up )
  306.         {
  307.             fprintf( stderr, "Bad line in table...\n\t%s\n", buf ) ;
  308.             Usage_() ;
  309.         }
  310.     }
  311.  
  312.     return ;
  313. }
  314. /*
  315.  *  GET_HEX - Get the value of two hex digits
  316.  */
  317.     unsigned char
  318. get_hex( buf, foul_up )
  319.     unsigned char   buf[] ;
  320.     Bool            *foul_up ;
  321. {
  322.     int     i ;
  323.     unsigned char   nib[2],
  324.                     c ;
  325.  
  326.     for( i = 0 ; i < 2 ; i++ )
  327.     {
  328.         nib[ i ] = -1;
  329.         c = buf[ i ] ;
  330.         if( c >= 0x30 && c <= 0x39 )        /* 0...9*/
  331.             nib[ i ] = c - 0x30;
  332.         else if( c > 0x40 && c < 0x47 )     /* A...F*/
  333.             nib[ i ] = 9 + c - 0x40;
  334.         else if( c > 0x60 && c < 0x67 )     /* a...f*/
  335.             nib[ i ] = 9 + c - 0x60;
  336.  
  337.         if( nib[ i ] == -1 )
  338.             *foul_up = TRUE ;
  339.     }
  340.  
  341.     c = ( nib[ 0 ] << 4 ) | nib[ 1 ] ;
  342.  
  343.     return( c ) ;
  344. }
  345.